package com.ease.concurrent.threadpool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author: chenhs
 * @date: Created in 21:47 2019/11/3
 **/
public class FixedSizeThreadPool {

    /**
     * 仓库
     */
    private BlockingQueue<Runnable> taskQueue;
    /**
     * 存放线程集合
     */
    private List<Worker> workers;


    private volatile boolean working = true;

    /**
     * @param poolSize 线程池大小
     * @param taskQueueSize 任务队列大小
     */
    public FixedSizeThreadPool(int poolSize, int taskQueueSize) {
        if (poolSize <= 0 || taskQueueSize <= 0) {
            throw new IllegalArgumentException("参数错误");
        }

        //初始化任务队列
        this.taskQueue = new LinkedBlockingQueue<>(taskQueueSize);

        //创建线程集合
        this.workers = Collections.synchronizedList(new ArrayList<>());

        //初始化工作线程
        for (int i = 0; i < poolSize; i++) {
            Worker w = new Worker(this);
            this.workers.add(w);
            //工作线程启动
            w.start();
        }

    }

    /**
     * 关闭线程池
     */
    public void shutdown() {
        if (working) {
            this.working = false;
            //如果工作线程处于阻塞状态，唤醒。
            for (Thread t : this.workers) {
                if (Thread.State.BLOCKED.equals(t.getState()) || Thread.State.WAITING.equals(t.getState())) {
                    //中断阻塞状态
                    System.out.println(t.getName()+"----当前已无任务，不待命等候，中断睡眠！");
                    t.interrupt();
                }
            }

        }
    }

    /**
     * 提交任务
     *
     * @param task
     * @return
     */
    public boolean submit(Runnable task) {
        if (!working) {
            return false;
        }
        return this.taskQueue.offer(task);
    }

    /**
     * 工作线程
     */
    private class Worker extends Thread {

        private FixedSizeThreadPool pool;

        public Worker(FixedSizeThreadPool pool) {
            this.pool = pool;
        }

        @Override
        public void run() {
            //方便查看线程计数（测试）
            int taskCount = 0;

            //从仓库取出任务执行
            while (this.pool.working || this.pool.taskQueue.size() > 0) {
                Runnable task = null;
                try {
                    if (this.pool.working) {
                        //队列为空时，阻塞
                        task = this.pool.taskQueue.take();
                    } else {
                        task = this.pool.taskQueue.poll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (task != null) {
                    try {
                        task.run();
                        System.out.println("线程："+ Thread.currentThread().getName() + " 执行完成 " + (++taskCount));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println(Thread.currentThread().getName() + "结束 ");
        }
    }


    public static void main(String[] args) {
        FixedSizeThreadPool pool = new FixedSizeThreadPool(3, 5);

        for (int i = 0; i < 5; i++) {
            pool.submit(() -> {
                System.out.println("任务开始......");

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        pool.shutdown();
    }

}
